﻿using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using TelescopeScripting.Controls;
using TelescopeScripting.Logic;

namespace TelescopeScripting
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private string rtguiPath;
        public MainWindow()
        {
            InitializeComponent();
            Application.Current.ShutdownMode = ShutdownMode.OnMainWindowClose;
            rtguiPath = "";
            while (rtguiPath.Equals("")) //we have to get this path before moving on.  make sure the user sets it!
            {
                rtguiPath = Scripting.SetRTGUIPath();
            }
        }

        private void ExecuteCommands_Click_1(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;
            if (button == null)
            { return; }
            string commands = Scripting.ParseCommands(this.ScriptingCommands.Items);
            string output = Scripting.ExecuteScript(commands, rtguiPath, false);
        }

        private void AddCommand_Click_1(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;

            if (button == null)
            { return; }

            if (this.ScriptingCommands.Items.Count <= 25)
            {
                string command = Scripting.ParseCommand(this.ComboBoxCommand.Text, this.CommandValue.Text);
                this.ScriptingCommands.Items.Add(command);
            }
            else
            {
                MessageBox.Show("You can't add more than 25 commands to a script!");
            }
        }

        private void AddPlayList_Click(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;

            if (button == null)
            { return; }

            if (!this.ScriptNameLabel.Text.Equals(""))
            {
                string playList = this.ScriptNameLabel.Text.ToString();
                this.PlayListCommands.Items.Add(playList);
                //save it after we add it the playlist so we can go get it!
                string myDocsTelescoping = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\TelescopeScripting\Scripts\" + ScriptNameLabel.Text + ".tscr";

                if (!Directory.Exists(System.IO.Path.GetDirectoryName(myDocsTelescoping))) //create the directory if it doesn't already exist
                {
                    Directory.CreateDirectory(System.IO.Path.GetDirectoryName(myDocsTelescoping));
                }

                File.WriteAllText(myDocsTelescoping, Scripting.ParseCommands(this.ScriptingCommands.Items)); //write the commands to a script file
            }
        }


        private void Up_Click_1(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;

            if (button == null)
            {
                return;
            }

            int currentIndex = this.ScriptingCommands.SelectedIndex;

            if (currentIndex > 0)
            {
                string toMoveUp = this.ScriptingCommands.SelectedItem.ToString();
                this.ScriptingCommands.Items.RemoveAt(currentIndex);
                this.ScriptingCommands.Items.Insert(currentIndex - 1, toMoveUp);
                this.ScriptingCommands.SelectedIndex = currentIndex - 1;
            }
        }

        private void Remove_Click_1(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;

            if (button == null)
            {
                return;
            }
            if (this.ScriptingCommands.Items.Count > 0 && this.ScriptingCommands.SelectedIndex >= 0)
            {
                int currentSelected = this.ScriptingCommands.SelectedIndex;
                this.ScriptingCommands.Items.RemoveAt(this.ScriptingCommands.SelectedIndex);
                if (this.ScriptingCommands.Items.Count > 0)
                {
                    this.ScriptingCommands.SelectedIndex = currentSelected--;
                }
            }
        }

        private void Down_Click_1(object sender, RoutedEventArgs e)
        {
            Button button = sender as Button;

            if (button == null)
            {
                return;
            }

            int currentIndex = this.ScriptingCommands.SelectedIndex;
            if (currentIndex < this.ScriptingCommands.Items.Count - 1)
            {
                string toMoveDown = this.ScriptingCommands.SelectedItem.ToString();
                this.ScriptingCommands.Items.RemoveAt(currentIndex);
                this.ScriptingCommands.Items.Insert(currentIndex + 1, toMoveDown);
                this.ScriptingCommands.SelectedIndex = currentIndex + 1;
            }

        }

        private void MenuItem_Save(object sender, RoutedEventArgs e)
        {
            if (!ScriptNameLabel.Text.Equals(""))
            {
                string myDocsTelescoping = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\TelescopeScripting\Scripts\" + ScriptNameLabel.Text + ".tscr";

                if (!Directory.Exists(System.IO.Path.GetDirectoryName(myDocsTelescoping))) //create the directory if it doesn't already exist
                {
                    Directory.CreateDirectory(System.IO.Path.GetDirectoryName(myDocsTelescoping));
                }

                File.WriteAllText(myDocsTelescoping, Scripting.ParseCommands(this.ScriptingCommands.Items)); //write the commands to a script file
            }
        }

        private void MenuItem_Open(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            string myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\TelescopeScripting\Scripts\";
            dialog.Title = "Open a script file";
            dialog.InitialDirectory = myDocs;
            dialog.Filter = "tscr files (*.tscr)|*.tscr";
            string commands = "";

            if (dialog.ShowDialog() != null)
            {
                if (!dialog.FileName.Equals("") && Directory.Exists(System.IO.Path.GetDirectoryName(dialog.FileName)))
                {
                    while (!this.ScriptingCommands.Items.IsEmpty) //empty the command list before opening a new one
                    {
                        this.ScriptingCommands.Items.RemoveAt(0);
                    }
                    commands = File.ReadAllText(dialog.FileName);
                    ScriptNameLabel.Text = System.IO.Path.GetFileNameWithoutExtension(dialog.FileName);

                    string[] commandArray = commands.Split(';'); //split the array of commands

                    foreach (string command in commandArray)
                    {
                        string com = command;
                        com = command.Replace(" ", ""); //remove white space
                        this.ScriptingCommands.Items.Add(com);
                    }
                }
            }
        }

        private void MenuItem_Close(object sender, RoutedEventArgs e)
        {
            Window.GetWindow(this).Close();
        }

        private void MenuItem_New(object sender, RoutedEventArgs e)
        {
            while (!this.ScriptingCommands.Items.IsEmpty)
            {
                this.ScriptingCommands.Items.RemoveAt(0);
            }
            this.ScriptNameLabel.Text = "";
        }

        private void MenuItem_NewPlaylist(object sender, RoutedEventArgs e)
        {
            while (!this.PlayListCommands.Items.IsEmpty)
            {
                this.PlayListCommands.Items.RemoveAt(0);
            }
            this.PlayListNameLabel.Text = "";
        }
        private void MenuItem_OpenPlaylist(object sender, RoutedEventArgs e)
        {
            OpenFileDialog dialog = new OpenFileDialog();
            string myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\TelescopeScripting\PlayLists\";
            dialog.Title = "Find a playlist and select it";
            dialog.InitialDirectory = myDocs;
            dialog.Filter = "tspl files (*.tspl)|*.tspl";
            string playList = "";

            if (dialog.ShowDialog() != null)
            {
                if (!dialog.FileName.Equals("") && Directory.Exists(System.IO.Path.GetDirectoryName(dialog.FileName)))
                {
                    while (!this.PlayListCommands.Items.IsEmpty) //empty the command list before opening a new one
                    {
                        this.PlayListCommands.Items.RemoveAt(0);
                    }
                    playList = File.ReadAllText(dialog.FileName);
                    PlayListNameLabel.Text = System.IO.Path.GetFileNameWithoutExtension(dialog.FileName);

                    string[] playListArray = playList.Split(','); //split the array of commands

                    foreach (string script in playListArray)
                    {
                        string scr = script;
                        scr = script.Replace(" ", ""); //remove white space
                        this.PlayListCommands.Items.Add(scr);
                    }
                }
            }
        }
        private void MenuItem_SavePlaylist(object sender, RoutedEventArgs e)
        {
            string myDocs = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\TelescopeScripting\PlayLists\";

            if (!Directory.Exists(System.IO.Path.GetDirectoryName(myDocs))) //create the directory if it doesn't already exist
            {
                Directory.CreateDirectory(System.IO.Path.GetDirectoryName(myDocs));
            }

            if (!PlayListNameLabel.Text.Equals("")) //make sure we have a playlist file
            {
                File.WriteAllText(myDocs + PlayListNameLabel.Text + ".tspl", Scripting.ParsePlayList(this.PlayListCommands.Items));
            }
        }

        private void MenuItem_RTGUIPath(object sender, RoutedEventArgs e)
        {
            rtguiPath = "";
            string myDocsTelescoping = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\TelescopeScripting\rtguiPath.dat";

            if (File.Exists(myDocsTelescoping))
            {
                File.Delete(myDocsTelescoping);
            }

            while (rtguiPath.Equals("")) //we have to get this path before moving on.  make sure the user sets it!
            {
                rtguiPath = Scripting.SetRTGUIPath();
            }
        }

        private void CommandValue_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (CommandValue.Text.Length <= 40)
            {
                //do nothing, we don't care
            }
            else
            {
                MessageBox.Show("The maximum length for a command is 40 characters!");
            }
        }

        private void InsertCommand_Click(object sender, RoutedEventArgs e)
        {
            if (this.ScriptingCommands.Items.Count <= 25)
            {
                string command = Scripting.ParseCommand(this.ComboBoxCommand.Text, this.CommandValue.Text);
                if (this.ScriptingCommands.SelectedIndex < 0)
                {
                    this.ScriptingCommands.Items.Insert(0, command);
                }
                else
                {
                    this.ScriptingCommands.Items.Insert(this.ScriptingCommands.SelectedIndex, command);
                }
            }
            else
            {
                MessageBox.Show("You can't add more than 25 commands to a script!");
            }
        }

        private void InsertPlayList_Click(object sender, RoutedEventArgs e)
        {
            string script = this.ScriptNameLabel.Text; //just add the script name from the right
            if (this.PlayListCommands.SelectedIndex < 0)
            {
                this.PlayListCommands.Items.Insert(0, script);
            }
            else
            {
                this.PlayListCommands.Items.Insert(this.PlayListCommands.SelectedIndex, script);
            }

            //save it after we add it the playlist so we can go get it!
            string myDocsTelescoping = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\TelescopeScripting\Scripts\" + ScriptNameLabel.Text + ".tscr";

            if (!Directory.Exists(System.IO.Path.GetDirectoryName(myDocsTelescoping))) //create the directory if it doesn't already exist
            {
                Directory.CreateDirectory(System.IO.Path.GetDirectoryName(myDocsTelescoping));
            }

            File.WriteAllText(myDocsTelescoping, Scripting.ParseCommands(this.ScriptingCommands.Items)); //write the commands to a script file
        }

        private void UpPlay_Click_1(object sender, RoutedEventArgs e)
        {
            int currentIndex = this.PlayListCommands.SelectedIndex;

            if (currentIndex > 0)
            {
                string toMoveUp = this.PlayListCommands.SelectedItem.ToString();
                this.PlayListCommands.Items.RemoveAt(currentIndex);
                this.PlayListCommands.Items.Insert(currentIndex - 1, toMoveUp);
                this.PlayListCommands.SelectedIndex = currentIndex - 1;
            }
        }

        private void RemovePlay_Click_1(object sender, RoutedEventArgs e)
        {
            if (this.PlayListCommands.Items.Count > 0 && this.PlayListCommands.SelectedIndex >= 0)
            {
                int currentSelected = this.PlayListCommands.SelectedIndex;
                this.PlayListCommands.Items.RemoveAt(this.PlayListCommands.SelectedIndex);
                if (this.PlayListCommands.Items.Count > 0)
                {
                    this.PlayListCommands.SelectedIndex = currentSelected++;
                }
            }

        }

        private void DownPlay_Click_1(object sender, RoutedEventArgs e)
        {
            int currentIndex = this.PlayListCommands.SelectedIndex;
            if (currentIndex < this.PlayListCommands.Items.Count - 1)
            {
                string toMoveDown = this.PlayListCommands.SelectedItem.ToString();
                this.PlayListCommands.Items.RemoveAt(currentIndex);
                this.PlayListCommands.Items.Insert(currentIndex + 1, toMoveDown);
                this.PlayListCommands.SelectedIndex = currentIndex + 1;
            }
        }

        private void ExecutePlayList_Click_1(object sender, RoutedEventArgs e)
        {
            this.Dispatcher.Invoke((Action)(() =>
            {
                if (this.PlayListCommands.Items.Count > 0)
                {
                    foreach (string script in this.PlayListCommands.Items) //need to execute each script in the playlist
                    {
                        string scriptPath = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments) + @"\TelescopeScripting\Scripts\" + script + ".tscr";
                        //open the script from the playlist
                        if (File.Exists(scriptPath))
                        {
                            string commands = File.ReadAllText(scriptPath);
                            Thread playlistThread = new Thread(new ThreadStart((Action)(() =>
                                {
                                    Scripting.ExecuteScript(commands, rtguiPath, true);
                                })));
                            playlistThread.IsBackground = true;
                            playlistThread.Start();
                            while (playlistThread.IsAlive)
                            {
                                Thread.Sleep(1000);
                            }
                            //string output = Scripting.ExecuteScript(commands, rtguiPath, true);
                        }
                    }
                }
            }));
        }

        private void ScriptingCommands_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
        {
            ListBox item = sender as ListBox;

            if (item == null)
            { return; }

            if (item.SelectedItems.Count <= 0)
            { return; }

            string selectedItem = item.SelectedItem.ToString();
            string[] commandVal = selectedItem.Split('=');

            this.ComboBoxCommand.Text = commandVal[0];
            this.CommandValue.Text = commandVal[1];
        }

        private void ModifyCommand_Click_1(object sender, RoutedEventArgs e)
        {
            if (this.ScriptingCommands.SelectedIndex >= 0)
            {
                //modify the selected listbox item!
                int currentIndex = this.ScriptingCommands.SelectedIndex;
                string command = Scripting.ParseCommand(this.ComboBoxCommand.Text, this.CommandValue.Text);
                this.ScriptingCommands.Items.RemoveAt(this.ScriptingCommands.SelectedIndex);
                this.ScriptingCommands.Items.Insert(currentIndex, command);
            }
        }

        private void ComboBoxCommand_SelectionChanged_1(object sender, SelectionChangedEventArgs e)
        {
            this.CommandValue.Text = "";
            this.CommandValue.Focus();
        }

        private void StopCommands_Click_1(object sender, RoutedEventArgs e)
        {
            try
            {
                foreach (Process proc in Process.GetProcessesByName("RTGUI"))
                {
                    proc.Kill();
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }


        private void MenuItem_CreateCatalog(object sender, RoutedEventArgs e)
        {
            CreateCatalogControl control = new CreateCatalogControl(rtguiPath);
            Window createCatalog = new Window()
            {
                Title = "Create catalog",
                SizeToContent = System.Windows.SizeToContent.WidthAndHeight,
                ResizeMode = System.Windows.ResizeMode.NoResize,
                Content = control,
                WindowStyle = System.Windows.WindowStyle.ToolWindow,
                WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner
            };
            createCatalog.ShowDialog();
        }

    }
}
